Imports System.Windows.Forms
Imports WRDB.Project

Public Class frmMapping

    Const REGAPP = "WRDB6"

    Private dgvStations, dgvParameters As WRDB.Controls.DGVEditor
    Private _Project As WRDB.Project.clsProject

    ''' <summary>
    ''' Instantiate form and initialize
    ''' </summary>
    ''' <param name="lstStations">Tab-separated list of station id and name</param>
    ''' <param name="lstParameters">Tab-separated list of pcode, name, and units</param>
    ''' <param name="Project">WRDB project</param>
    Public Sub New(ByVal lstStations As Generic.List(Of String), ByVal lstParameters As Generic.List(Of String), ByRef Project As WRDB.Project.clsProject)

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        _Project = Project
        Initialize(lstStations, lstParameters)
    End Sub

    Friend Sub Initialize(ByVal lstStations As Generic.List(Of String), ByVal lstParameters As Generic.List(Of String))
        Try
            Dim dtStations As New DataTable
            Dim dtParameters As New DataTable

            Dim ps As New clsProjectSettings(_Project)

            For i As Integer = 1 To 2
                Dim dt As DataTable = Choose(i, dtStations, dtParameters)
                Dim lstFrom As Generic.List(Of String) = Choose(i, lstStations, lstParameters)
                Dim lstTo As New Generic.List(Of String)
                _Project.FillPickList(lstTo, "", Choose(i, "Stations", "PCodes"), Choose(i, "Station_ID", "PCode"), Choose(i, "Station_Name", "Anal_Name"), "(Create New)")

                Dim dg As DataGridView = Choose(i, dgStations, dgParameters)

                With dt
                    .Columns.Add("Import", GetType(Boolean))
                    .Columns.Add(Choose(i, "Station", "Parameter") & " Code", GetType(String))
                    .Columns.Add(Choose(i, "Station", "Parameter") & " Name", GetType(String))
                    .Columns.Add("Units", GetType(String))
                    .Columns.Add("Convert To", GetType(String))
                    .Columns.Add("Multiplier", GetType(Single))
                    For Each s As String In lstFrom
                        Dim ar() As String = s.Split(vbTab)
                        If i = 1 Then
                            .Rows.Add(True, ar(0), Strings.Left(ar(1), 60))
                        Else
                            .Rows.Add(True, ar(0), Strings.Left(ar(1), 60), ar(2))
                        End If
                    Next
                End With

                With dg
                    .DataSource = dt
                    .AllowUserToAddRows = False
                    .AllowUserToDeleteRows = False
                    .AllowUserToOrderColumns = False
                    .AllowUserToResizeColumns = False
                    .AllowUserToResizeRows = False
                    For j As Integer = 1 To 6
                        With .Columns(j - 1)
                            .SortMode = DataGridViewColumnSortMode.NotSortable
                            .HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
                            .HeaderCell.Style.WrapMode = DataGridViewTriState.False
                            Select Case j
                                Case 5 : .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
                                Case Else : .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
                            End Select
                            Select Case j
                                Case 1 : .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                                Case 6 : .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                                Case Else : .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
                            End Select
                            Select Case j
                                Case 2 To 4 : .ReadOnly = True : .DefaultCellStyle.ForeColor = Drawing.Color.Gray
                                Case Else : .ReadOnly = False : .DefaultCellStyle.ForeColor = Drawing.Color.Black
                            End Select
                        End With
                    Next
                End With

                Dim dgv As WRDB.Controls.DGVEditor = Choose(i, dgvStations, dgvParameters)
                dgv = New WRDB.Controls.DGVEditor(dg)
                dgv.SetColumnFormat(WRDB.Controls.DGVEditor.enumColumnTypes.ComboBox, 4, lstTo)
                If i = 1 Then
                    dgvStations = dgv
                    dg.Columns(3).Visible = False
                    dg.Columns(5).Visible = False
                Else
                    dgvParameters = dgv
                End If

                'override "convert to" values with entries in registry
                For Each r As DataRow In dg.DataSource.Rows
                    Dim KeyPrefix As String = "DownloadMapping\" & Choose(i, "Stations\", "Parameters\") & r.Item(1)

                    Dim s As String = ps.GetKey(KeyPrefix & "\Convert", "")
                    r.Item(0) = ps.GetKey(KeyPrefix & "\Checked", "False")

                    For Each sTo As String In lstTo
                        If sTo.StartsWith(s & " - ") Then
                            r.Item(4) = sTo
                            Exit For
                        End If
                    Next
                    If IsDBNull(r.Item(4)) Then r.Item(0) = False
                    If i = 2 Then r.Item(5) = ps.GetKey(KeyPrefix & "\Mult", "1.0")
                Next

                dg.Sort(dg.Columns(1), System.ComponentModel.ListSortDirection.Ascending)

                UpdateLabels(dg)
            Next

        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub frm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        GetWindowPos(REGAPP, Me)
        dtStart.Format = System.Windows.Forms.DateTimePickerFormat.Custom
        dtStart.CustomFormat = MyDateFormat()
        dtEnd.Format = System.Windows.Forms.DateTimePickerFormat.Custom
        dtEnd.CustomFormat = MyDateFormat()
    End Sub

    Private Sub frm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        Try
            SaveWindowPos(REGAPP, Me)
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Dim ps As New clsProjectSettings(_Project)

        For i As Integer = 1 To 2
            Dim dg As DataGridView = Choose(i, dgStations, dgParameters)
            Dim cnt As Integer = 0
            For Each r As DataRow In dg.DataSource.Rows
                If r.Item(0) AndAlso (Not IsDBNull(r.Item(4)) Or Not dg.Columns(4).Visible) Then
                    cnt += 1
                    If cnt > 20 Then Exit For 'don't want to clog up ini file with too many entries!
                    Dim KeyPrefix As String = "DownloadMapping\" & Choose(i, "Stations\", "Parameters\") & r.Item(1)
                    ps.SetKey(KeyPrefix & "\Checked", r.Item(0))
                    ps.SetKey(KeyPrefix & "\Convert", _Project.GetPickList(r.Item(4)))
                    If i = 2 Then ps.SetKey(KeyPrefix & "\Mult", r.Item(5))
                End If
            Next
            UpdateLabels(dg)
        Next
        ps.Save()
        SaveSetting(REGAPP, Name, "StartDate", dtStart.Value)
        SaveSetting(REGAPP, Name, "EndDate", dtEnd.Value)
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub ContextMenuStrip1_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ContextMenuStrip1.ItemClicked
        Try
            With CType(CType(CType(sender, ContextMenuStrip).SourceControl, DataGridView).DataSource, DataTable)
                For Each r As DataRow In .Rows
                    r.Item(0) = e.ClickedItem Is CheckAllToolStripMenuItem
                Next
            End With
            UpdateLabels(CType(sender, ContextMenuStrip).SourceControl)
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    ''' <summary>
    ''' Return dictionary of selected stations where key is imported value and value is stationID to convert to
    ''' </summary>
    Friend Function SelectedStations() As Generic.Dictionary(Of String, String)
        Dim dict As New Generic.Dictionary(Of String, String)
        Dim dt As DataTable = dgStations.DataSource
        For Each r As DataRow In dt.Rows
            If r.Item(0) And Not IsDBNull(r.Item(4)) And Not dict.ContainsKey(r.Item(1)) Then dict.Add(r.Item(1), _Project.GetPickList(r.Item(4)))
        Next
        Return dict
    End Function

    ''' <summary>
    ''' Return dictionary of selected pcodes where key is imported value and value is 2 item array: PCode to convert to and multiplier
    ''' </summary>
    Friend Function SelectedParameters() As Generic.Dictionary(Of String, String())
        Dim dict As New Generic.Dictionary(Of String, String())
        Dim dt As DataTable = dgParameters.DataSource
        For Each r As DataRow In dt.Rows
            Dim ar(1) As String
            ar(0) = _Project.GetPickList(TestNull(r.Item(4), ""))
            ar(1) = TestNull(r.Item(5), 1.0)
            If r.Item(0) And Not IsDBNull(r.Item(4)) And Not dict.ContainsKey(r.Item(1)) Then dict.Add(r.Item(1), ar)
        Next
        Return dict
    End Function

    Private Sub dgParameters_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgParameters.CellValueChanged, dgStations.CellValueChanged
        Try
            If e.RowIndex < 0 Then Exit Sub

            With CType(sender, DataGridView)

                Dim FieldLength As Integer = IIf(sender Is dgStations, 25, 10)
                Dim cbo As DataGridViewComboBoxColumn = .Columns(4)

                If e.ColumnIndex = 0 Then 'update label
                    UpdateLabels(sender)
                    'if check it and haven't already selected a Station or pcode, automatically create one
                    'per Tim Wool 4/16/13 use Storet codes to create default IDs, but strip out _WQX and replace : with space
                    If TestNull(.Item(0, e.RowIndex).Value, "False") = True AndAlso TestNull(.Item(4, e.RowIndex).Value, "") = "" Then
                        'Dim NewItem As String = Strings.Left(.Item(1, e.RowIndex).Value, FieldLength).ToUpper.Trim.Replace(", ", "_").Replace(" ", "_").Replace(",", "_").Replace("; ", "_")
                        Dim NewItem As String = Strings.Left(.Item(1, e.RowIndex).Value.ToUpper.Trim.Replace("_WQX", "").Replace(":", " ").Replace(", ", "_").Replace("; ", "_"), FieldLength)
                        If NewItem.EndsWith("_") Then NewItem = NewItem.Substring(0, NewItem.Length - 1)
                        cbo.Items.Add(NewItem)
                        .Item(4, e.RowIndex).Value = NewItem
                    End If
                ElseIf e.ColumnIndex = 4 Then
                    If .Item(e.ColumnIndex, e.RowIndex).Value.startswith("(Create") Then
                        Dim OrigName As String = .Item(1, e.RowIndex).Value
                        Dim TableName As String = IIf(sender Is dgStations, "Stations", "PCodes")
                        Dim FieldName As String = IIf(sender Is dgStations, "Station_ID", "PCode")
                        Dim DescName As String = IIf(sender Is dgStations, "Station_Name", "Anal_Name")
                        Dim dgv As WRDB.Controls.DGVEditor = IIf(sender Is dgStations, dgvStations, dgvParameters)

                        Dim NewItem As String = InputBox(String.Format("Enter the new {0} you wish to add (later you can edit the Support table to add the name and other fields):", FieldName.Replace("_", " ")),
                                                         String.Format("Create New {0}", FieldName), OrigName.ToUpper.Substring(0, Math.Min(OrigName.Length, FieldLength))).ToUpper.Trim


                        If NewItem = "" Then 'cancelled, try to set to first item in list
                            If cbo.Items.Count > 1 Then .Item(e.ColumnIndex, e.RowIndex).Value = cbo.Items(1)
                        Else
                            If NewItem.Length > FieldLength Then
                                WarningMsgFmt("The PCode must be no more than {0} characters.", FieldLength)
                            ElseIf _Project.DB.GetRecordList("PCodes", "PCode").Contains(NewItem) Then
                                WarningMsg("The PCode you entered already exists.")
                            Else
                                'don't add to table yet or update routine can't add other good info (and may decide to cancel anyway)
                                Dim lst As New Generic.List(Of String)
                                For Each s As String In cbo.Items
                                    lst.Add(s)
                                Next
                                If Not lst.Contains(NewItem) Then lst.Add(NewItem)
                                dgv.SetColumnFormat(WRDB.Controls.DGVEditor.enumColumnTypes.ComboBox, e.ColumnIndex, lst)
                                .Item(e.ColumnIndex, e.RowIndex).Value = NewItem
                            End If
                        End If
                    End If
                    .Item(0, e.RowIndex).Value = Not String.IsNullOrEmpty(.Item(2, e.RowIndex).Value)
                End If
            End With
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub dgParameters_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgParameters.CurrentCellDirtyStateChanged, dgStations.CurrentCellDirtyStateChanged
        With CType(sender, DataGridView)
            If .CurrentCell.ColumnIndex = 2 Then
                .EndEdit()
            Else
                If .IsCurrentCellDirty Then .CommitEdit(DataGridViewDataErrorContexts.Commit)
            End If
        End With
    End Sub

    Private Sub UpdateLabels(ByVal dg As DataGridView)
        With dg
            Dim cnt As Integer = 0
            For r As Integer = 0 To .RowCount - 1
                If .Item(0, r).Value Then cnt += 1
            Next
            If dg Is dgStations Then
                lblNumStations.Text = "Stations Selected: " & cnt
            Else
                lblNumPCodes.Text = "Parameters Selected: " & cnt
            End If
        End With
    End Sub

    Private Sub lnkSelectAll_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lnkSelectAll.LinkClicked
        dtStart.Value = dtStart.MinDate
        dtEnd.Value = dtEnd.MaxDate
    End Sub

    Private Sub dtStart_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtStart.ValueChanged, dtEnd.ValueChanged
        lblDates.Text = String.Format("Date Range: {0:d} to {1:d}", dtStart.Value, dtEnd.Value)
    End Sub

    Private Sub btnSelectAllSta_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSelectAllSta.Click, btnSelectNoneSta.Click, btnSelectAllPCode.Click, btnSelectNonePCode.Click
        Try
            Dim dg As DataGridView = IIf(sender Is btnSelectAllSta Or sender Is btnSelectNoneSta, dgStations, dgParameters)
            Dim IsChecked As Boolean = sender Is btnSelectAllSta Or sender Is btnSelectAllPCode
            With CType(dg.DataSource, DataTable)
                Dim FieldLength As Integer = IIf(dg Is dgStations, 25, 10)
                Dim cbo As DataGridViewComboBoxColumn = dg.Columns(4)
                Dim lst As New Generic.List(Of String)
                For Each s As String In cbo.Items
                    lst.Add(s)
                Next
                For Each r As DataRow In .Rows
                    r.Item(0) = IsChecked
                    If IsChecked AndAlso TestNull(r.Item(4), "") = "" Then
                        'Dim NewItem As String = Strings.Left(r.Item(2), FieldLength).ToUpper.Trim.Replace(", ", "_").Replace(" ", "_").Replace(",", "_")
                        Dim NewItem As String = Strings.Left(r.Item(1).ToUpper.Trim.Replace("_WQX", "").Replace(":", " ").Replace(", ", "_").Replace("; ", "_"), FieldLength)
                        r.Item(4) = NewItem
                        If Not lst.Contains(NewItem) Then lst.Add(NewItem)
                    End If
                    If Not IsChecked Then r.Item(4) = ""
                Next
                cbo.Items.Clear()
                cbo.Items.AddRange(lst.ToArray)
            End With
            dg.Refresh()
            UpdateLabels(dg)
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub btnHelp_Click(sender As System.Object, e As System.EventArgs) Handles btnHelp.Click
        With CType(Me.Owner, frmDownload)
            .ShowHelp(Me, frmDownload.HelpTopicID)
        End With
    End Sub
End Class
